﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Feeds.Interop;
using System.Collections;
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace Bonobo.Reader.Feeds
{
    public sealed class FeedChannelManager
    {
        FeedsManager _manager;

        public FeedChannelManager()
        {
            _manager = new FeedsManager();
        }

        public void CreateChannel(Uri url, String path, String name)
        {
            var folder = CreateFolder(path);
            var pathStr = (String.IsNullOrEmpty(path) ? path : path.Substring(1) + "\\");

            if (!_manager.ExistsFeed(pathStr + name))
            {
                folder.CreateFeed(name, url.AbsoluteUri);
            }
        }

        private IFeedFolder CreateFolder(String path)
        {
            var folderNames = path.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);

            var currentFolder = ((IFeedFolder)_manager.RootFolder);

            for (int i = 0; i < folderNames.Length; i++)
            {
                currentFolder = CreateFolder(currentFolder, folderNames[i]);
            }

            return currentFolder;
        }

        private IFeedFolder CreateFolder(IFeedFolder folder, String name)
        {
            if (!folder.ExistsSubfolder(name))
            {
                return (IFeedFolder)folder.CreateSubfolder(name);
            }
            else
            {
                return (IFeedFolder)folder.GetSubfolder(name);
            }
        }

        public void DeleteChannel(String path)
        {
            if (_manager.ExistsFeed(path))
            {
                _manager.DeleteFeed(path);
            }
        }

        public void DeleteFolder(String path)
        {
            if (_manager.ExistsFolder(path))
            {
                _manager.DeleteFolder(path);
            }
        }

        public void ImportOpml(Stream input)
        {
            using (var reader = new XmlTextReader(input))
            {
                var doc = XDocument.Load(reader);
                var body = (from n in doc.Descendants("body") select n).First();
                ParseOutline(body.Elements("outline"));
            }
        }

        private void ParseOutline(IEnumerable<XElement> outlines)
        {
            foreach (var outline in outlines)
            {
                if (outline.Attribute("type") != null && outline.Attribute("type").Value == "rss")
                {
                    var titleAttr = outline.Attribute("title");
                    var urlAttr = outline.Attribute("xmlUrl");
                    if (titleAttr != null && urlAttr != null)
                    {
                        CreateChannel(new Uri(urlAttr.Value), GetPath(outline), titleAttr.Value);
                    }
                }
                else
                {
                    CreateFolder(GetPath(outline));
                }
                ParseOutline(outline.Elements("outline"));
            }
        }

        private String GetPath(XElement outline)
        {
            if (outline.Parent != null && outline.Parent.Name == "outline")
            {
                return GetPath(outline.Parent) + GetTopLevelPath(outline);
            }             
            else
            {
                return GetTopLevelPath(outline);
            }
        }

        private String GetTopLevelPath(XElement outline)
        {
            if (outline.Attribute("type") == null && outline.Attribute("title") != null)
            {
                return "\\" +outline.Attribute("title").Value;
            }
            else
            {
                return String.Empty;
            }
        }
    }
}
